import { dialog } from 'electron';
import * as os from 'node:os';
import path from 'node:path';
import { ETableRowType, ICodeRow, ICodeTableData, ITableRow } from './types';

/** 获得RimeConfig路径 */
export function getRimeConfigDir() {
  const userHome = os.homedir();
  switch (os.platform()) {
    case 'darwin':
      return path.join(`${userHome}/Library/Rime`); // macOS
    case 'linux':
      return path.join(`${userHome}/.config/ibus/rime/`);
    case 'win32':
      return path.join(`${userHome}/AppData/Roaming/Rime`); // windows
    default:
      return '';
  }
}


/** 转换有效行 */
export function convertCodeRow(trimmedLine: string, content: ITableRow[]) {
  // 使用正则表达式匹配逗号、空格、制表符
  const regex = /[ ,\t]+/g;
  // 按正则分割字符串
  const columns = trimmedLine.split(regex);

  const lineIndex = content.length - 1;
  if (columns.length < 2) {
    dialog.showMessageBox({
      type: 'error',
      title: '错误',
      message: `文件第${lineIndex - 1}行：读取文件编码错误：码 或 编码，不得为空`
    });
  }

  const weightIndex = findWeightIndex(columns);
  // stem weight后一个
  // text 第1个
  const text = columns[0];

  // 原始分割符
  const originalSeparator = trimmedLine[trimmedLine.indexOf(text) + text.length];
  // code 第1到weight前一个
  const code = columns
    .slice(1, weightIndex ? weightIndex : columns.length)
    .join(' ');
  let weight = '', stem = '';
  if (weightIndex) {
    weight = columns[weightIndex];
    stem = columns.slice(weightIndex + 1, columns.length).join(' ');
  }
  const codeRow: ICodeRow = {
    lineIndex,
    text,
    code,
    weight,
    stem,
    originalSeparator
  };

  return codeRow;
}


/** 获得字段类型 */
function getColumnType(row: string): string | null {
  // 定义正则表达式
  const regex = /^-\s*(code|text|weight|stem)/;

  // 测试字符串是否匹配正则表达式
  const match = row.match(regex);

  // 如果匹配成功，返回捕获组中的值，否则返回 null
  return match ? match[1] : null;
}


/** 返回权重的索引 */
function findWeightIndex(columns: string[]) {
  // 使用正则表达式验证是否为纯大于0的整数
  const regex = /^[1-9]\d*$/;
  const index = columns.findIndex((item) => regex.test(item));
  return index > 0 ? index : false;
}

/** 状态接口 */
interface ILineState {
  handleLine(line: string, context: CodeTableConverter): void;
}

/** 普通行状态 */
class NormalLineState implements ILineState {
  handleLine(line: string, context: CodeTableConverter): void {
    const trimmedLine = line.trim();

    // 检查是否是多行注释的开始
    if (trimmedLine.startsWith('---')) {
      context.setState(new MultilineCommentStartState());
      context.converterLine(line);
      return;
    }

    // 检查是否是空行
    if (trimmedLine === '') {
      const row: ITableRow = {
        rowType: ETableRowType.EMPTY,
        originalRow: line
      };
      context.addContent(row);
      return;
    }

    // 检查是否是单行注释
    if (trimmedLine.startsWith('#')) {
      const row: ITableRow = {
        rowType: ETableRowType.COMMENT,
        originalRow: line
      };
      context.addContent(row);
      return;
    }

    // 处理普通代码行
    const row: ITableRow = {
      rowType: ETableRowType.CODE,
      originalRow: line
    };
    context.addContent(row);
    context.addCodeRow(convertCodeRow(trimmedLine, context.getContent()));
  }
}

/** 多行注释状态 */
class MultilineCommentState implements ILineState {
  handleLine(line: string, context: CodeTableConverter): void {
    const trimmedLine = line.trim();
    const row: ITableRow = {
      rowType: ETableRowType.MULTILINE_COMMENT,
      originalRow: line
    };

    // 检查是否是多行注释的结束
    if (trimmedLine.startsWith('---') || trimmedLine.startsWith('...')) {
      const endRow: ITableRow = {
        rowType: ETableRowType.MULTILINE_COMMENT_END,
        originalRow: line
      };
      context.addContent(endRow);
      context.setState(new NormalLineState());
      return;
    }

    // 检查是否进入列定义状态
    if (trimmedLine.startsWith('columns:')) {
      context.setState(new ColumnsDefinitionState());
      context.addContent(row);
      return;
    }

    context.addContent(row);
  }
}

/** 列定义状态 */
class ColumnsDefinitionState implements ILineState {
  handleLine(line: string, context: CodeTableConverter): void {
    const trimmedLine = line.trim();
    const row: ITableRow = {
      rowType: ETableRowType.MULTILINE_COMMENT,
      originalRow: line
    };

    // 检查是否是多行注释的结束
    if (trimmedLine.startsWith('---') || trimmedLine.startsWith('...')) {
      const endRow: ITableRow = {
        rowType: ETableRowType.MULTILINE_COMMENT_END,
        originalRow: line
      };
      context.addContent(endRow);
      context.setState(new NormalLineState());
      return;
    }

    // 处理列定义
    if (trimmedLine.startsWith('-')) {
      const column = getColumnType(trimmedLine);
      if (column) {
        context.addColumn(column);
      }
    }

    context.addContent(row);
  }
}

/** 空行状态 */
class EmptyLineState implements ILineState {
  handleLine(line: string, context: CodeTableConverter): void {
    const row: ITableRow = {
      rowType: ETableRowType.EMPTY,
      originalRow: line
    };
    context.addContent(row);
    context.setState(new NormalLineState());
  }
}

/** 单行注释状态 */
class SingleLineCommentState implements ILineState {
  handleLine(line: string, context: CodeTableConverter): void {
    const row: ITableRow = {
      rowType: ETableRowType.COMMENT,
      originalRow: line
    };
    context.addContent(row);
    context.setState(new NormalLineState());
  }
}

/** 多行注释开始状态 */
class MultilineCommentStartState implements ILineState {
  handleLine(line: string, context: CodeTableConverter): void {
    const row: ITableRow = {
      rowType: ETableRowType.MULTILINE_COMMENT_START,
      originalRow: line
    };
    context.addContent(row);
    context.getColumns().length = 0; // 清空数组
    context.setState(new MultilineCommentState());
  }
}

/** 字典文件 */
export class CodeTableConverter {
  private currentState: ILineState;
  private columns: string[] = [];
  private content: ITableRow[] = [];
  private codeRows: ICodeRow[] = [];

  get codeTableData(): ICodeTableData {
    return {
      filePath: this.filePath,
      content: this.content,
      codeRows: this.codeRows
    };
  }

  constructor(private filePath: string) {
    this.currentState = new NormalLineState();
  }

  setState(state: ILineState): void {
    this.currentState = state;
  }

  // 公共方法供状态类使用
  addContent(row: ITableRow): void {
    this.content.push(row);
  }

  addCodeRow(codeRow: ICodeRow): void {
    this.codeRows.push(codeRow);
  }

  addColumn(column: string): void {
    this.columns.push(column);
  }

  getContent(): ITableRow[] {
    return this.content;
  }

  getColumns(): string[] {
    return this.columns;
  }

  converterLine(originalLine: string): void {
    // 让当前状态处理行
    this.currentState.handleLine(originalLine, this);
  }
}


export const DEFAULT_CONFIG_PATH = getRimeConfigDir();
